home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Transfer
- */
-
- #include "include/config.h"
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/socket.h>
-
- #include <netdb.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <netinet/tcp.h>
- #include <bsdsocket/socketbasetags.h>
- #include <error.h>
- #include <time.h>
-
- #include "include/mui.h"
- #include <MUI/NListview_mcc.h>
- #include "include/download.h"
- #include "include/upload.h"
- #include "include/gui.h"
- #include "include/panel.h"
- #include "include/prefs.h"
- #include "include/transfer.h"
- #include "amster_Cat.h"
- #include "include/protos.h"
-
-
- MUIF translistdisp(REG(a2) char **array, REG(a1) songtrans sd)
- {
- static char buf2[50],buf3[50],buf4[50],buf5[50];
-
- static char *states[] = {
- (char *)_MSG_TRANS_STAT_PREPARE,
- (char *)_MSG_TRANS_STAT_QUEUE,
- (char *)_MSG_TRANS_STAT_WAIT,
- (char *)_MSG_TRANS_STAT_CONN,
- (char *)_MSG_TRANS_STAT_REQ,
- (char *)_MSG_TRANS_STAT_INIT,
- (char *)_MSG_TRANS_STAT_DL,
- (char *)_MSG_TRANS_STAT_UL,
- (char *)_MSG_TRANS_STAT_FIN,
- (char *)_MSG_TRANS_STAT_ABORT,
- (char *)_MSG_TRANS_STAT_ERROR,
- NULL
- };
-
- static char *errors[] = {
- (char *)_MSG_TRANS_STAT_ERROR,
- (char *)_MSG_TRANS_ERROR_FILEOPEN,
- (char *)_MSG_TRANS_ERROR_FILEREAD,
- (char *)_MSG_TRANS_ERROR_FILEWRITE,
- (char *)_MSG_TRANS_ERROR_NET_UNKNOWN,
- (char *)_MSG_TRANS_ERROR_LOGGEDOUT,
- (char *)_MSG_TRANS_ERROR_NOTFOUND,
- (char *)_MSG_TRANS_ERROR_INVALIDREQUEST,
- (char *)_MSG_TRANS_ERROR_TEASER,
- (char *)_MSG_TRANS_ERROR_BUSY,
- NULL
- };
-
- static char *NetError[] = {
- (char *)_MSG_TRANS_ERROR_NET_TIMEOUT,
- (char *)_MSG_TRANS_ERROR_NET_REFUSED,
- (char *)_MSG_TRANS_ERROR_NET_RESET,
- (char *)_MSG_TRANS_ERROR_NET_PIPE,
- NULL
- };
-
- if(states[0] == (char *)_MSG_TRANS_STAT_PREPARE)
- localize_array(states);
-
- if(errors[0] == (char *)_MSG_TRANS_STAT_ERROR)
- localize_array(errors);
-
- if(NetError[0] == (char *)_MSG_TRANS_ERROR_NET_TIMEOUT)
- localize_array(NetError);
-
- if(sd) {
- *array++ = nap_strippath(sd->song->title);
-
- if (sd->state == DLS_WAIT) {
- sprintf(buf5, states[sd->state], sd->ErrorCode);
- *array++ = buf5;
- }
- else if (sd->state != DLS_ERROR)
- *array++ = states[sd->state];
- else {
- switch (sd->error) {
- case ERROR_FILEOPEN:
- case ERROR_FILEREAD:
- case ERROR_FILEWRITE:
- sprintf(buf5, errors[sd->error], sd->ErrorCode);
- *array++ = buf5;
- break;
- case ERROR_NET:
- switch (sd->ErrorCode) {
- case ETIMEDOUT:
- *array++ = NetError[ERROR_NET_TIMEOUT];
- break;
- case ECONNREFUSED:
- *array++ = NetError[ERROR_NET_REFUSED];
- break;
- default:
- sprintf(buf5, errors[sd->error], sd->ErrorCode);
- *array++ = buf5;
- }
- break;
- default:
- *array++ = errors[sd->error];
- }
- }
-
- if (sd->size > 0)
- sprintf(buf2,"\33r%ld / %ld (%d%%)", sd->cur, sd->size, (sd->cur*100+5)/sd->size);
- else sprintf(buf2, "\33r0"); /* Can this happen? */
- *array++ = buf2;
-
- if (sd->cps > 0) {
- if (sd->stalltick<5) { /* 5 seconds */
- sprintf(buf3,"%d",sd->cps);
- *array++ = buf3;
- }
- else {
- *array++ = (char *)MSG_TRANS_STAT_STALLED;
- }
- sprintf(buf4,"%ld:%02ld / %ld:%02ld",sd->transtime/60,sd->transtime%60,sd->timeleft/60,sd->timeleft%60);
- *array = buf4;
- }
- else {
- *array++ = "-";
- *array = "-";
- }
-
- }
- else {
- *array++ = (char *)MSG_LH_FILE;
- *array++ = (char *)MSG_LH_STATE;
- *array++ = (char *)MSG_LH_SIZE;
- *array++ = (char *)MSG_LH_CPS;
- *array = (char *)MSG_LH_ETIME;
- }
- return(0);
- }
-
-
- ULONG dl_setup(struct IClass *cl, Object *obj, Msg msg)
- {
- struct TransferData *data = INST_DATA(cl,obj);
-
- if (!DoSuperMethodA(cl,obj,msg))
- return(FALSE);
-
- DoMethod(_app(obj), MUIM_Application_AddInputHandler, &data->ihnode);
-
- return(TRUE);
- }
-
-
- ULONG dl_muicleanup(struct IClass *cl, Object *obj, Msg msg)
- {
- struct TransferData *data = INST_DATA(cl,obj);
-
- DoMethod(_app(obj), MUIM_Application_RemInputHandler, &data->ihnode);
-
- return(DoSuperMethodA(cl,obj,msg));
- }
-
-
- void CalculateCps(songtrans sd)
- {
- if (sd->cur != sd->oldsize) {
- sd->stalltick = 0;
- sd->oldsize = sd->cur;
- }
- else sd->stalltick++;
-
- sd->transtime = time(NULL) - sd->starttime;
- if (sd->transtime == 0) sd->transtime = 1;
- sd->cps = (sd->cur - sd->resumestart) / sd->transtime;
- if (sd->cps > 0)
- sd->timeleft = (sd->size - sd->cur) / sd->cps;
- else sd->timeleft = 0;
- }
-
-
- void TransferSetError(struct TransferData *data, char *title, char *user, int error)
- {
- u_long tmp;
- songtrans sd;
- long i;
-
- for (i=0; ; i++) {
- DoMethod(data->list, MUIM_NList_GetEntry, i, &tmp);
- if (!tmp) return;
- sd = (songtrans)tmp;
- if (strcmp(sd->song->title, title) == 0 && stricmp(sd->song->user, user) == 0) break;
- }
-
- sd->state = DLS_ERROR;
- sd->error = error;
-
- if (sd->type == TYPE_DOWNLOAD_OUT || sd->type == TYPE_DOWNLOAD_IN) DoMethod(gui->dwin, DL_UPDATE, sd);
- else DoMethod(gui->uwin, UPLOAD_UPDATE, sd);
- }
-
-
- void TransferInfo(struct TransferData *data)
- {
- static char buf[600];
- u_long tmp;
- songtrans sd;
-
- GetAttr(MUIA_NList_EntryClick, data->list, &tmp);
- if (tmp == -1 || tmp == -2) return;
- DoMethod(data->list, MUIM_NList_GetEntry, tmp, &sd);
- if (!sd) return;
-
- if(sd->host[0] == '\0') {
- sprintf(buf, "%s (%s)", sd->song->user, Inet_NtoA(sd->song->ip));
- }
- else {
- sprintf(buf, "%s (%s)", sd->song->user, sd->host);
- }
-
- set(data->info, MUIA_Text_Contents, buf);
- }
-
-
- void TransferCleanup(struct TransferData *data)
- {
- u_long item;
- int i=0, j;
-
- while (1) {
- DoMethod(data->list, MUIM_NList_GetEntry, i, &item);
- if (!item) break;
- j = ((songtrans)item)->state;
- if (j >= DLS_FIN) {
- DoMethod(data->list,MUIM_NList_Remove,i);
- nap_songfree(((songtrans)item)->song);
- if (((songtrans)item)->fname) free(((songtrans)item)->fname);
- free((songtrans)item);
- } else i++;
- }
- }
-
-
- void TransferHandleError(songtrans sd)
- {
- char error[128];
-
- if (sd->error != 0) {
- sd->state = DLS_ERROR;
- if (sd->error >= ERROR_FILEOPEN && sd->error <= ERROR_FILEWRITE) {
- Fault(sd->ErrorCode, "", error, 127);
- gui_debugf((char *)MSG_INFO_IOERROR, sd->fname, error);
- }
- else if (sd->error >= ERROR_OUTOFBOUND) sd->error = ERROR_UNKNOWN;
- prf_event(PRFE_DLERROR);
- }
- else if (sd->state == DLS_FIN) {
- if (sd->type == TYPE_DOWNLOAD_OUT || sd->type == TYPE_DOWNLOAD_IN) prf_event(PRFE_DLFINISH);
- else prf_event(PRFE_ULFINISH);
- }
-
- if (sd->type == TYPE_DOWNLOAD_OUT || sd->type == TYPE_DOWNLOAD_IN) DoMethod(gui->dwin, DL_UPDATE, sd);
- else DoMethod(gui->uwin, UPLOAD_UPDATE, sd);
- }
-
-
- /* Thread stuff */
-
- BOOL InitTransferThread(thread t, songtrans sd)
- {
- struct Library *DosBase;
- struct Library *SocketBase;
- char *buffer;
- long s;
- long tmp;
- struct hostent *he;
-
- sd->state = DLS_PREP;
-
- sd->nsig = AllocSignal(-1);
- if (sd->nsig == -1) {
- ExitTransferThread(sd, 1);
- return FALSE;
- }
- sd->nsigm = (1L << (sd->nsig));
- sd->msigm = (1L << (t->port->mp_SigBit));
-
- DosBase = OpenLibrary("dos.library", 0);
- if (!DosBase) {
- ExitTransferThread(sd, 1);
- return FALSE;
- }
- sd->DosBase = DosBase;
-
- SocketBase = OpenLibrary("bsdsocket.library", 0);
- if (!SocketBase) {
- ExitTransferThread(sd, 1);
- return FALSE;
- }
- sd->SocketBase = SocketBase;
- SocketBaseTags(SBTM_SETVAL(SBTC_SIGIOMASK), (char *)sd->nsigm, TAG_DONE);
-
- buffer = malloc(8192);
- if (!buffer) {
- ExitTransferThread(sd, 2);
- return FALSE;
- }
- sd->buffer = buffer;
-
- /* Perform DNS-lookup */
- he = gethostbyname(Inet_NtoA(sd->song->ip));
- he = gethostbyaddr(he->h_addr_list[0], he->h_length, AF_INET);
- if (he != 0) strcpy(sd->host, he->h_name);
- else strcpy(sd->host, Inet_NtoA(sd->song->ip));
-
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s<0) {
- ExitTransferThread(sd, 3);
- return FALSE;
- }
- sd->s = s;
-
- sd->sin.sin_addr.s_addr = sd->ip;
- sd->sin.sin_port = sd->port;
- sd->sin.sin_family = AF_INET;
- sd->sin.sin_len = sizeof(sd->sin);
-
- tmp = 1;
- IoctlSocket(s, FIOASYNC, (char *)&tmp);
- IoctlSocket(s, FIONBIO, (char *)&tmp);
- /* Asynchronous and non-blocking I/O to the socket */
-
- tmp = connect(s, (struct sockaddr *)&sd->sin, sizeof(sd->sin));
- if (tmp == -1 && Errno() != EINPROGRESS) {
- sd->ErrorCode = Errno();
- ExitTransferThread(sd, ERROR_NET);
- return FALSE;
- }
-
- thr_message(t, DLC_STATE, (APTR)DLS_CON);
-
- return TRUE;
- }
-
-
- void ExitTransferThread(songtrans sd, int ret)
- {
- struct Library *DosBase=sd->DosBase;
- struct Library *SocketBase=sd->SocketBase;
-
- if (sd->nsig != -1) FreeSignal(sd->nsig);
- sd->nsig = -1;
-
- if (sd->f) Close(sd->f);
- sd->f = 0;
-
- if (sd->s != -1) CloseSocket(sd->s);
- sd->s = -1;
-
- if (sd->buffer) free(sd->buffer);
- sd->buffer = NULL;
-
- if (SocketBase) CloseLibrary(SocketBase);
- sd->SocketBase = NULL;
-
- if (DosBase) CloseLibrary(DosBase);
- sd->DosBase = NULL;
-
- thr_exit(sd->t, ret);
- }
-